<template>
  <!-- :before-upload="beforeUpload" -->
  <a-upload
    v-model:file-list="fileList"
    :accept="accept"
    :list-type="listType"
    :action="apiDomain + '/common/upload'"
    name="file"
    :headers="{
      'x-access-token': token,
    }"
    :showUploadList="showUploadList"
    :disabled="disabled"
    :max-count="maxCount"
    @preview="handlePreview"
    @change="handleChange"
    @drop="handleDrop"
  >
    <template v-if="!loading">
      <div v-if="!disabled">
        <div v-if="(fileList.length < maxCount && listType !== 'picture-card') || !showUploadList">
          <a-button>
            <upload-outlined></upload-outlined>
            {{  title }}
          </a-button>
        </div>
        <div v-else> 点击上传 </div>
      </div>
    </template>
    <a-spin :spinning="loading" v-else>
    </a-spin>
  </a-upload>
  <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
    <img alt="example" style="width: 100%" :src="previewImage" />

  </a-modal>
</template>

<script setup>
  import { UploadOutlined } from '@ant-design/icons-vue';
  import { ref, watch } from 'vue';
  import { message } from 'ant-design-vue';
  import { defineProps } from 'vue';
  import { cloneDeep } from 'lodash-es';
  
  import { getToken } from '@/utils/token'
  import { BASEURL } from '@/utils/const'

  // 定义 emit 方法
  const emit = defineEmits(['change', 'loading']);

  // 定义接收的 props
  const props = defineProps({
    file: {
      type: String,
    },
    listType: {
      type: String,
      default: 'picture-card',
    },
    maxCount: {
      type: Number,
      default: 1,
    },
    accept: {
      type: String,
      default: 'image/*',
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    showUploadList: {
      default: true,
      type: Boolean,
    },
    title: {
      default: '点击上传源文件',
      type: String,
    },
  });

  const token = getToken();
  const apiDomain = BASEURL;
  const loading = ref(false)

  watch(loading.value, () => {
    console.log('发生变化')
    emit('loading', loading.value)
  })

  //   图片上传
  const fileList = ref([]);
  // 查看大图
  const previewVisible = ref(false);

  const setFiles = () => {
    let fileArr = [];
    fileList.value = []
    if (props.file.includes(',')) {
      fileArr = props.file.split(',');
    } else {
      if(props.file) {
        fileArr = [props.file];
      }
    }
    let arr = []
    for (let i of fileArr) {
      arr.push({
        thumbUrl: i,
        url: i,
        imageUrl: i,
        name: i,
      });
    }
    fileList.value = arr
  
  }
  // 判断是否有默认图片
  if (props.file) {
    setFiles()
  }
  watch(props.file, (newVal, oldVal) => {
    setFiles()
  });


  let timerIndex = 0
  let timer = setInterval(() => {
    setFiles()
    timerIndex++
    if(fileList.value.length > 0 || timerIndex > 10) {
      clearInterval(timer)
      timerIndex = 0
    }
  }, 200);

  // 监听图片结果
  watch(fileList, (newVal, oldVal) => {
    let ok = true;
    for (let i of newVal) {
      if (!i.thumbUrl) {
        ok = false;
        return;
      }
    }
    if (ok) {
      loading.value = false
      emit('loading', loading.value)
      emit('change', cloneDeep(newVal));
    }
  });

  const beforeUpload = (file) => {
    return new Promise((resolve) => {
      if (props.accept !== 'image/*') {
        resolve(file);
        return;
      }
      compressImage(file).then((res) => {
        resolve(res);
      });
    });
  };

  function compressImage(file, maxWidth = 800, quality = 1) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.src = URL.createObjectURL(file);

    
       

      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');

        let width = img.width;
        let height = img.height;

        // 如果宽度大于最大宽度，则等比例缩放
        if (width > maxWidth) {
          height *= maxWidth / width;
          width = maxWidth;
        }

        // 设置canvas尺寸
        canvas.width = width;
        canvas.height = height;

        // 绘制图片到canvas
        ctx.drawImage(img, 0, 0, width, height);

        // 将canvas内容转换为Blob对象
        canvas.toBlob(
          (blob) => {
            if (blob) {
              resolve(blob);
            } else {
              reject(new Error('Canvas to Blob conversion failed'));
            }
          },
          'image/jpeg',
          quality
        );
      };

      img.onerror = (error) => {
        reject(error);
      };
    });
  }

  // 上传变化
  const handleChange = async (info) => {
    const status = info.file.status;
    loading.value = true
    emit('loading', loading.value)
    if (status === 'done') {
      const response = info.file.response;
      if (response.success) {
        for (let i of fileList.value) {
          if (i.uid === info.file.uid) {
            // i.thumbUrl = apiDomain + response.message;
            // i.url = apiDomain + '/' + response.message;
            i.imageUrl = response.result.imageUrl;
            break;
          }
        }
        let emitData = [];
        for (let i of info.fileList) {
          emitData.push(cloneDeep(i));
        }
        emit('change', emitData);
        message.success(`上传成功！`);
      } else {
        message.error(message.message);
      }
      loading.value = false
      emit('loading', loading.value)
    } else if (status === 'error') {
      message.error(`上传失败！`);
      loading.value = false
      emit('loading', loading.value)
    }
  };
  function handleDrop(e) {}

  const previewImage = ref('');
  const previewTitle = ref('');
  function getBase64(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result);
      reader.onerror = (error) => reject(error);
    });
  }
  const handlePreview = async (file) => {
    if (props.accept !== 'image/*') return;
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }
    previewImage.value = file.url || file.preview;
    previewVisible.value = true;
    previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
  };
  const handleCancel = () => {
    previewVisible.value = false;
    previewTitle.value = '';
  };
</script>

<style scoped></style>
